Securing Cookies, Sessions, and User Credentials in Java Web Applications
Course: Advanced Java Training
Topic: Securing Cookies, Sessions, and User Credentials
Course Link: Advanced Java Training Course
Demo Link: Register for a Course Demo
Website: JustAcademy
1. Introduction to Web Application Security
Web application security protects user identities, login credentials, session information, and private data from unauthorized access. In Java web applications, cookies and sessions help maintain user state across HTTP requests, while authentication mechanisms verify a user's identity.
Cookies are commonly used to carry session identifiers between a browser and a server. The server uses the session identifier to locate session information and determine whether the user has an authenticated session. If an attacker steals or misuses a valid session identifier, the attacker may be able to impersonate the user.
Secure credential handling, cookie configuration, session lifecycle management, password hashing, and access-control checks must work together to protect a web application.
2. Learning Objectives
- Understand cookies, sessions, and user credentials.
- Differentiate authentication, session management, and authorization.
- Configure secure cookie attributes in Java applications.
- Manage HttpSession objects safely.
- Prevent session fixation, session hijacking, and credential exposure.
- Understand secure password storage and password verification.
- Apply HTTPS, CSRF protection, and appropriate session timeouts.
- Implement secure login and logout workflows.
- Recognize common security mistakes and test application defenses.
3. Understanding Cookies
A cookie is a small piece of data that a website asks a browser to store. The browser may send the cookie back to the website with subsequent requests when its domain, path, security, and other cookie rules permit it.
In Java Servlet applications, a session identifier is often transported through a cookie named JSESSIONID. The cookie normally carries an identifier, not the entire server-side session object.
Common Uses of Cookies
- Maintaining a session identifier.
- Remembering non-sensitive user preferences.
- Supporting certain authentication flows.
- Maintaining limited state across browser requests.
Types of Cookies
| Cookie Type |
Description |
Example |
| Session cookie |
Typically has no explicit persistent expiration date and is intended for the browser session. |
A session identifier. |
| Persistent cookie |
Has an expiration time or maximum age and may remain stored after the browser session. |
A language preference. |
| Secure cookie |
Uses the Secure attribute to restrict transmission to HTTPS connections. |
A protected session cookie. |
| HttpOnly cookie |
Uses the HttpOnly attribute to prevent ordinary JavaScript access through document.cookie. |
A session identifier. |
| SameSite cookie |
Controls whether the browser sends the cookie with cross-site requests. |
A cookie configured with Lax or Strict. |
4. Understanding HTTP Sessions
HTTP is stateless by default. Each request is handled independently unless the application uses a mechanism to associate requests with a user or workflow. A session provides a way to preserve selected state across multiple requests.
Java Servlet applications commonly use the HttpSession interface to manage server-side session data.
Example of Session Data
- Authenticated user ID.
- Temporary shopping-cart information.
- Application preferences.
- Temporary workflow state.
A session should not be treated as a place to store everything about a user. Avoid storing plaintext passwords, unnecessary sensitive information, or payment credentials in session attributes. Keep session data minimal and control access to it.
5. Authentication, Session Management, and Authorization
| Concept |
Purpose |
Example |
| Authentication |
Verifies the user's identity. |
Validating a password and a second authentication factor. |
| Session management |
Maintains authenticated state across requests. |
Associating requests with a server-side session. |
| Authorization |
Determines which resources and operations are allowed. |
Restricting the administration dashboard to administrators. |
| Credential storage |
Protects stored authentication secrets. |
Storing password hashes instead of plaintext passwords. |
These mechanisms solve different problems. A user may be authenticated but still lack permission to access a resource. Likewise, a secure cookie does not make a weak password-storage system safe.
6. Important Cookie Security Attributes
6.1 Secure
The Secure attribute tells the browser to send the cookie only over secure HTTPS connections. It helps prevent the session identifier from being transmitted over unencrypted HTTP.
6.2 HttpOnly
The HttpOnly attribute prevents ordinary client-side JavaScript from reading the cookie through interfaces such as document.cookie. This helps reduce session-cookie theft through some cross-site scripting attacks, but it does not eliminate XSS or prevent malicious scripts from making authenticated requests.
6.3 SameSite
The SameSite attribute controls whether a cookie is included with cross-site requests.
- Strict: Provides stricter restrictions on sending cookies with cross-site requests.
- Lax: Allows cookies in certain top-level cross-site navigations while restricting many other cross-site contexts.
- None: Allows cross-site cookie sending and requires Secure in modern browsers.
Choose the setting that suits the application's authentication and navigation requirements. SameSite is an additional CSRF defense, not a complete replacement for CSRF tokens or other appropriate protections.
6.4 Path and Domain
The Path attribute limits the request paths for which a browser sends a cookie. The Domain attribute can allow a cookie to be sent to a domain and its eligible subdomains. Avoid setting Domain unnecessarily because broader cookie scope increases exposure.
6.5 Max-Age and Expires
These attributes control cookie persistence. Use persistent authentication cookies only when the application requires them and has appropriate protections, including revocation and expiration controls. A session cookie disappearing when a browser closes is not a reliable substitute for server-side session expiration.
7. Configuring Secure Session Cookies in Java
Cookie configuration should be handled through the servlet container or framework's supported configuration whenever possible. The exact configuration depends on the servlet version and application server.
Example Using web.xml
<session-config>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
<session-timeout>15</session-timeout>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
This example configures HttpOnly and Secure session cookies, sets a 15-minute inactivity timeout, and restricts session tracking to cookies. Ensure that the application is served over HTTPS when Secure is enabled. Cookie SameSite configuration may require container-specific settings, a framework feature, or suitable response configuration.
Example Set-Cookie Header
Set-Cookie: __Host-SessionID=opaque-random-value; Path=/; Secure; HttpOnly; SameSite=Lax
The __Host- prefix has special browser-enforced requirements: the cookie must use Secure, must use Path=/, and must not include a Domain attribute. Use a supported framework or container configuration to generate the actual session cookie rather than manually replacing the servlet container's session mechanism without a clear security design.
8. Creating and Accessing an HttpSession
The HttpSession interface provides methods for storing and retrieving server-side attributes. A session should generally be created when needed, such as after a successful login, rather than being created unnecessarily for every authentication check.
Example: Store Authenticated User Information
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
public class SessionHelper {
public static void establishSession(
HttpServletRequest request,
long authenticatedUserId,
String trustedRole) {
HttpSession session = request.getSession();
session.setAttribute("userId", authenticatedUserId);
session.setAttribute("role", trustedRole);
session.setMaxInactiveInterval(15 * 60);
}
}
Call this helper only after the application has successfully authenticated the user and obtained the role from a trusted source. This example illustrates session attributes and timeout configuration; the complete login workflow must also address session ID rotation and other security controls.
Modern Jakarta applications use jakarta.servlet. Older Java EE applications may use javax.servlet. Use the namespace that matches the project's dependencies and server.
Useful HttpSession Methods
| Method |
Purpose |
request.getSession() |
Returns the current session or creates one if necessary. |
request.getSession(false) |
Returns an existing session or null if no session exists. |
session.setAttribute() |
Stores a session attribute. |
session.getAttribute() |
Retrieves a session attribute. |
session.removeAttribute() |
Removes a session attribute. |
session.invalidate() |
Invalidates the session. |
session.setMaxInactiveInterval() |
Sets the inactivity timeout in seconds. |
9. Preventing Session Fixation
Session fixation occurs when an attacker attempts to make a victim use a session identifier already known to the attacker. If the application authenticates the user without replacing the identifier, the attacker may be able to reuse it.
Rotate the session ID after successful authentication and after relevant privilege changes. In Servlet 3.1 and later, request.changeSessionId() can change the current session identifier while retaining the session attributes.
Example: Rotate the Session ID After Authentication
// Call only after credentials have been validated.
HttpSession session = request.getSession();
request.changeSessionId();
session.setAttribute("userId", authenticatedUser.getId());
session.setAttribute("role", authenticatedUser.getRole());
This is a simplified example. In production, use the security framework's supported login flow when available, and ensure that the session is rotated at the correct point in the authentication process.
10. Preventing Session Hijacking
Session hijacking occurs when an attacker obtains and reuses a valid session identifier. Since the session ID may effectively act as a bearer credential, protecting it is essential.
Prevention Techniques
- Use HTTPS across the entire authenticated application.
- Set the Secure and HttpOnly cookie attributes.
- Choose an appropriate SameSite policy.
- Rotate session IDs after login and relevant privilege changes.
- Set appropriate idle and absolute session expiration limits.
- Invalidate sessions during logout and relevant account-security events.
- Never put session IDs in URLs or expose them in logs.
- Protect the application against XSS and CSRF attacks.
- Require reauthentication for high-risk actions when appropriate.
- Monitor unusual authentication activity without collecting unnecessary sensitive data.
11. Session Timeout and Expiration
Session expiration limits how long a session can remain active. An inactivity timeout ends a session after a period without requests, while an absolute timeout limits the total lifetime of a session regardless of activity.
Configure an Inactivity Timeout
HttpSession session = request.getSession();
session.setMaxInactiveInterval(900); // 15 minutes
Configure a Default Timeout
<session-config>
<session-timeout>15</session-timeout>
</session-config>
The web.xml timeout is expressed in minutes, while setMaxInactiveInterval() uses seconds. Absolute session lifetime may require additional framework or application logic.
Session Expiration Best Practices
- Choose timeouts based on the sensitivity and purpose of the application.
- Use shorter idle periods for sensitive administrative or financial workflows where appropriate.
- Handle expired sessions gracefully by requiring authentication again.
- Do not rely on browser closure to terminate a server-side session.
- Use server-side invalidation and expiration rather than simply deleting a browser cookie.
12. Secure Logout Implementation
Logout should invalidate the server-side session and clear any related authentication state managed by the security framework. A POST request is generally appropriate because logout changes the application's authentication state; protect the request with CSRF defenses where applicable.
import java.io.IOException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
}
response.sendRedirect(
request.getContextPath() + "/login.jsp");
}
}
This is a basic servlet example. If the application uses Spring Security or another authentication framework, use its logout mechanism so that security contexts, remember-me tokens, and related state are also handled correctly.
13. Securing User Credentials
User credentials are the information used to prove a user's identity. They may include passwords, passkeys, multifactor authentication secrets, recovery codes, and authentication tokens. These values must be protected both in transit and at rest.
Credential Security Principles
- Never store plaintext passwords in a database.
- Never log passwords or authentication secrets.
- Use a dedicated password-hashing algorithm for password storage.
- Use HTTPS for login, password changes, and authenticated requests.
- Apply rate limiting and monitoring to authentication endpoints.
- Provide secure password-reset and account-recovery workflows.
- Consider multifactor authentication for higher-risk accounts and operations.
- Store database credentials and service secrets in an appropriate secret-management system.
- Limit access to authentication records and sensitive logs.
14. Password Hashing and Verification
Password hashing transforms a password into a stored hash using a one-way password-hashing algorithm. During login, the submitted password is checked against the stored hash using the algorithm's verification process.
Unlike general-purpose hashes such as plain SHA-256, password-hashing algorithms are deliberately designed to make large-scale password guessing more expensive. Common choices include Argon2id, bcrypt, and PBKDF2, selected and configured according to current security guidance and application requirements.
Recommended Password Storage
| Approach |
Assessment |
| Plaintext password storage |
Unsafe; a database leak exposes the passwords directly. |
| Simple unsalted SHA-256 |
Unsuitable for password storage because it is too fast for this purpose. |
| Salted password hash using a dedicated password-hashing algorithm |
Recommended when configured correctly and supported by a maintained library. |
| Encryption of stored passwords |
Usually inappropriate for password verification because the original password can be recovered with the decryption key. |
Use a maintained security library to generate and verify password hashes. The library should handle salts and store the parameters required for verification. Do not invent a custom password-hashing algorithm.
15. Example Password Hashing with a Security Library
The following example illustrates the API style of Spring Security's BCryptPasswordEncoder. It assumes Spring Security is already included and configured in the project.
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
public class PasswordExample {
public static void main(String[] args) {
PasswordEncoder encoder =
new BCryptPasswordEncoder();
String rawPassword = "Example-Password-2026";
String passwordHash =
encoder.encode(rawPassword);
boolean valid =
encoder.matches(rawPassword, passwordHash);
System.out.println("Password valid: " + valid);
}
}
This is an educational example only. Never use the sample password as a real account password. In an actual application, create the encoder through the application's security configuration, select a suitable work factor, and store only the generated encoded hash. During login, call the encoder's verification method rather than comparing raw passwords.
16. Secure Login Workflow
A secure login workflow verifies credentials and establishes a protected authenticated session without exposing secrets.
Recommended Sequence
- Receive the login request over HTTPS.
- Validate the format and size of the submitted fields.
- Look up the user record using a parameterized database query.
- Verify the submitted password against the stored password hash.
- Apply rate limiting and other anti-abuse controls as appropriate.
- On successful authentication, rotate the session ID or use the framework's secure session-establishment process.
- Store only necessary identity information in the session or security context.
- Apply authorization checks to protected pages and operations.
- Return a generic failure message when authentication fails, avoiding unnecessary account enumeration.
Security Reminder
Do not trust a user ID, role, or authentication status supplied through an ordinary request parameter. Establish identity and permissions through trusted server-side authentication logic.
17. Preventing Cross-Site Request Forgery (CSRF)
CSRF is an attack in which a browser is induced to send an unwanted request to a website where the victim is already authenticated. Because browsers automatically attach eligible cookies, an attacker may attempt to trigger state-changing actions using the victim's session.
CSRF Protection Measures
- Use the CSRF protection provided by the application's security framework.
- Use unpredictable CSRF tokens for applicable state-changing requests.
- Choose a suitable SameSite cookie policy as an additional defense.
- Do not perform sensitive state changes through GET requests.
- Validate the request's origin or other relevant request context when appropriate.
SameSite is defense in depth, not a universal substitute for CSRF protection. The correct design depends on the application's architecture and authentication method.
18. Preventing Cross-Site Scripting (XSS)
XSS occurs when an application allows untrusted content to execute as script in a user's browser. If an attacker can run script in the application's origin, the attacker may perform actions as the user even when the session cookie is HttpOnly.
XSS Prevention Practices
- Use context-appropriate output encoding.
- Avoid inserting untrusted values into HTML or JavaScript without appropriate handling.
- Use safe templating practices and review any HTML sanitization requirements.
- Apply a suitable Content Security Policy as an additional defense.
- Keep client-side dependencies updated.
- Remember that HttpOnly prevents direct cookie reading by JavaScript but does not prevent every action an XSS payload can perform.
19. Protecting Credentials and Session Data in Logs
Logs help developers diagnose problems and investigate suspicious activity, but they can become a source of sensitive information if credentials or session identifiers are recorded.
Never Log
- Plaintext passwords.
- Complete session IDs or bearer tokens.
- Password-reset tokens or recovery codes.
- Database passwords and application secrets.
- Full authentication headers containing credentials.
Useful Security Events to Log
- Successful and failed authentication attempts.
- Account lockouts or rate-limit events.
- Password changes and recovery events.
- Session termination and important security events.
- Denied access to protected resources.
Protect logs with appropriate access controls, retention policies, and monitoring. Record enough information to investigate incidents without exposing reusable secrets.
20. Common Security Mistakes and Solutions
| Security Mistake |
Risk |
Recommended Solution |
| Storing plaintext passwords |
A database leak immediately exposes passwords. |
Use a dedicated password-hashing algorithm. |
| Missing Secure cookie attribute |
Cookies may be exposed over unencrypted HTTP. |
Use HTTPS and Secure cookies. |
| Missing HttpOnly attribute |
Client-side scripts may read the cookie. |
Set HttpOnly for session cookies. |
| No suitable SameSite policy |
Cookies may be sent in unwanted cross-site contexts. |
Choose an appropriate SameSite policy and apply CSRF protection. |
| Never rotating session IDs |
Session fixation risk may increase. |
Rotate the ID after authentication and relevant privilege changes. |
| Using unlimited session lifetimes |
Abandoned sessions may remain usable for too long. |
Configure inactivity and absolute timeouts. |
| Deleting only the browser cookie during logout |
A stolen copy may still identify an active server-side session. |
Invalidate the server-side session and related authentication state. |
| Storing tokens in localStorage without considering XSS |
Same-origin JavaScript may read the token. |
Prefer an appropriate HttpOnly cookie or a Backend-for-Frontend design where suitable. |
| Trusting client-provided roles |
Users may attempt to gain unauthorized privileges. |
Establish roles from trusted server-side identity data. |
| Logging passwords or session tokens |
Logs may expose reusable credentials. |
Redact secrets and restrict access to logs. |
21. Practical Exercise: Secure a Java Login Application
Project: Build a Java web application with secure credentials, protected sessions, and a logout workflow.
Project Requirements
- Create a user table containing an ID, username, password hash, and role.
- Build a login form that submits credentials over HTTPS.
- Use PreparedStatement for database queries involving user input.
- Verify passwords using a maintained password-hashing library.
- Rotate the session ID after successful authentication.
- Configure Secure, HttpOnly, and an appropriate SameSite cookie policy.
- Set a suitable inactivity timeout and consider an absolute timeout.
- Protect private pages with authentication and authorization checks.
- Implement logout using a state-changing request and invalidate the session.
- Ensure logs never contain plaintext passwords or reusable session tokens.
Testing Checklist
- Try opening a protected page without logging in.
- Enter incorrect credentials and check that the response does not expose sensitive details.
- Inspect session-cookie attributes in the browser's developer tools.
- Verify that the session ID changes after login.
- Log out and confirm that the old server-side session is no longer valid.
- Test session expiration after inactivity.
- Attempt a state-changing request without the required CSRF protection.
- Check that a regular user cannot access administrator-only features.
- Review application logs for accidental credential or token exposure.
22. Interview Questions and Answers
Q1. What is a cookie?
A cookie is a small value stored by a browser and sent with eligible requests to a website. It is commonly used to transport a session identifier.
Q2. What is an HTTP session?
An HTTP session maintains selected server-side state across multiple requests associated with a user or browser session.
Q3. What is the difference between cookies and sessions?
Cookies are stored on the client and sent with requests, while HttpSession data is maintained on the server. A cookie commonly carries the identifier used to locate the session.
Q4. What does the Secure cookie attribute do?
It restricts the browser from sending the cookie over unencrypted HTTP connections.
Q5. What does HttpOnly do?
It prevents ordinary JavaScript from accessing the cookie through interfaces such as document.cookie. It does not prevent every form of XSS exploitation.
Q6. What is the SameSite attribute?
SameSite controls whether cookies are sent with cross-site requests and can help reduce certain CSRF risks.
Q7. What is session fixation?
Session fixation is an attack in which a victim is induced to use a session identifier known to an attacker. Rotating the session ID after authentication helps prevent this attack.
Q8. What is session hijacking?
Session hijacking occurs when an attacker obtains and reuses a valid session identifier to impersonate a user.
Q9. Why should passwords be hashed?
Password hashing makes it harder to recover original passwords if the password database is exposed. Dedicated algorithms such as Argon2id, bcrypt, or PBKDF2 should be used rather than plain fast hashes.
Q10. Why should session IDs not be stored in URLs?
URLs can appear in browser history, server logs, bookmarks, and referrer information, creating opportunities for session identifier exposure.
Q11. Why is HTTPS important for sessions?
HTTPS encrypts data in transit, helping protect credentials and session identifiers from network interception or modification.
Q12. Does HttpOnly prevent CSRF?
No. HttpOnly restricts JavaScript access to a cookie, but the browser may still send the cookie with requests. CSRF requires separate appropriate defenses.
Q13. What is the purpose of session.invalidate()?
It invalidates the current server-side session and its attributes. Related authentication state should also be cleared through the framework or identity system when applicable.
Q14. Why should sensitive events require reauthentication?
Reauthentication can reduce the risk of unauthorized changes when a session has been stolen or left active on an unattended device.
23. Quick Revision Checklist
- Use HTTPS throughout authenticated workflows.
- Configure Secure and HttpOnly attributes for session cookies.
- Choose an appropriate SameSite policy.
- Keep session identifiers opaque and protect them as credentials.
- Rotate session IDs after login and relevant privilege changes.
- Configure inactivity and absolute session timeouts.
- Invalidate server-side sessions during logout.
- Store password hashes using a maintained password-hashing algorithm.
- Never log passwords, session IDs, or reusable tokens.
- Use CSRF protection and prevent XSS.
- Enforce server-side authorization on every protected operation.
- Test authentication, logout, cookie settings, and session expiration.
24. Conclusion
Securing cookies, sessions, and user credentials is essential for building trustworthy Java web applications. Cookies carry state between the browser and server, sessions maintain server-side user state, and credentials establish identity. Each component requires its own security controls.
Use HTTPS, secure cookie attributes, session ID rotation, reasonable timeouts, proper logout handling, strong password hashing, CSRF protection, XSS prevention, and server-side authorization checks. Applying these practices together helps reduce the risk of credential theft, session hijacking, and unauthorized access.
25. Learn More with JustAcademy
Explore the Advanced Java Training course to strengthen your understanding of Java web development, session management, and application security.
Register for a course demo to learn more about the training, or visit the JustAcademy website for additional learning resources.
26. References